#region

using Hangfire;
using Hangfire.Redis;

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

using Volo.Abp;
using Volo.Abp.BackgroundJobs.Hangfire;
using Volo.Abp.BackgroundJobs.RabbitMQ;
using Volo.Abp.Modularity;

#endregion

namespace Leo.Core.Shared.Module
{
    /// <summary>
    ///     后台任务模块
    /// </summary>
    [DependsOn(
        typeof(AbpBackgroundJobsRabbitMqModule),
        typeof(AbpBackgroundJobsHangfireModule)
    )]
    public class BackgroundJobModule : AbpModule
    {
        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder();
            var configuration = context.GetConfiguration();
            var path = configuration["BackgroundJob:Dashboard"];
            if (!string.IsNullOrEmpty(path))
            {
                app.UseHangfireDashboard(path);
            }
            else
            {
                app.UseHangfireDashboard();
            }
        }

        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            var configuration = context.Services.GetConfiguration();
            ConfigureBackgroundJob(context, configuration);
        }

        private void ConfigureBackgroundJob(ServiceConfigurationContext context, IConfiguration configuration)
        {
            var jobMode = configuration["BackgroundJob:Mode"];
            Console.WriteLine($"BackgroundJob:{jobMode}");
            if (!string.IsNullOrEmpty(jobMode) && jobMode.Equals("RabbitMq", StringComparison.OrdinalIgnoreCase))
            {
                var queueName = configuration["BackgroundJob:RabbitMq:QueueName"];
                if (string.IsNullOrEmpty(queueName))
                {
                    queueName = configuration["App:KeyPrefix"];
                }

                Configure<AbpRabbitMqBackgroundJobOptions>(options =>
                {
                    options.DefaultQueueNamePrefix = queueName + ".";
                });
            }
            else
            {
                var storage = configuration["BackgroundJob:Hangfire:Storage"];
                Console.WriteLine($"BackgroundJob storage:{storage}");
                if (!string.IsNullOrEmpty(storage) && storage.Equals("Redis", StringComparison.OrdinalIgnoreCase))
                {
                    var hangfireConnStr = configuration.GetConnectionString("Hangfire");
                    if (string.IsNullOrEmpty(hangfireConnStr))
                    {
                        hangfireConnStr = "localhost";
                    }
                    Console.WriteLine($"BackgroundJob hangfireConnStr:{hangfireConnStr}");
                    var queueName = configuration["BackgroundJob:Hangfire:QueueName"];
                    if (string.IsNullOrEmpty(queueName))
                    {
                        queueName = configuration["App:KeyPrefix"];
                    }

                    var db = configuration["BackgroundJob:Hangfire:Db"];
                    if (string.IsNullOrEmpty(db))
                    {
                        db = "1";
                    }

                    if (!int.TryParse(db, out int dbIndex))
                    {
                        dbIndex = 1;
                    }

                    context.Services.AddHangfire(config =>
                    {
                        var redisOptions = new RedisStorageOptions
                        {
                            Prefix = "hangfire:" + queueName.ToLower() + ":",
                            Db = dbIndex,
                            InvisibilityTimeout = TimeSpan.FromHours(3)
                        };
                        config.UseRedisStorage(hangfireConnStr, redisOptions);
                    });
                }
                else
                {
                    var hangfireConnStr = configuration.GetConnectionString("Hangfire");
                    if (string.IsNullOrEmpty(hangfireConnStr))
                    {
                        hangfireConnStr = configuration.GetConnectionString("Default");
                    }
                    Console.WriteLine($"BackgroundJob hangfireConnStr:{hangfireConnStr}");
                    context.Services.AddHangfire(config =>
                    {
                        config.UseSqlServerStorage(hangfireConnStr);
                    });
                }
            }
        }
    }
}